Skip to content

feat(tables): return only selected columns from the Table block query - #6954

Merged
j15z merged 4 commits into
stagingfrom
feat/table-block-filter-by-view
Aug 22, 2026
Merged

feat(tables): return only selected columns from the Table block query#6954
j15z merged 4 commits into
stagingfrom
feat/table-block-filter-by-view

Conversation

@j15z

@j15z j15z commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add columns to the v2 table row query: stable column ids or names, resolved against the table schema; a reference that matches no column is skipped and reported back in ignoredColumns
  • Table block gains a "Columns to Return" multi-select (new table.outputColumns selector — stores ids, shows names) for the query operation; the tool and block expose ignoredColumns as an output, and the block's description, best practices, and canvas sentence cover the new field
  • Projection happens inside the fetch loop, before byte accounting, so the 5MB budget and page cut measure only the returned columns; batch sizing stays bounded by the rows as stored (average and widest row seen), so a narrow projection over wide rows cannot request an oversized batch
  • Multi-select dropdowns keep a removable row for a selected value the loaded list no longer contains — including when that list is empty — shown by its id, so a deleted column can be cleared in place; column selectors read the table detail through fetchQuery with no second cache layer, so a deletion is reflected without a reload
  • Model-supplied columns survives when the block runs as an Agent tool; a malformed selection fails fast instead of widening to every column; a null filter (the sub-block default) is treated as absent
  • Workspace fork/duplicate of a copied table preserves selector-backed column picks; a <reference> in the advanced Table ID no longer leaks into selector fetches

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Other: ___________

Testing

Unit tests across the route, service drain loop (including batch sizing), block transformer, selectors, dropdown, subblock context, and fork remap; type-check, lint, check:api-validation, tool-metadata:check, and the full check:audits suite pass. Reviewers: the projection-before-budget change in lib/table/rows/service.ts is the part worth a close read — the drain now measures projected bytes for the budget but sizes batches from stored bytes.

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

Screenshots/Videos

UI change: the Table block's query operation gets a "Columns to Return" multi-select under the table picker; a selected column that has since been deleted shows as its raw col_… id with a matching row in the list so it can be toggled off. No screenshots attached.

@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 22, 2026 2:36am

Request Review

@cursor

cursor Bot commented Aug 21, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Touches the table query drain and 5MB byte-budget/page-cut logic, so a projection or batch-sizing bug could truncate, over-fetch, or fail large queries. Not auth-critical, but it is a core data-read path.

Overview
Lets Query Rows return only chosen columns so workflows can stay under the 5MB budget without fetching every field.

The v2 query API accepts columns (stable ids or names). Unknown refs are skipped and listed in ignoredColumns instead of failing. Projection runs inside fetchRowsBounded before byte accounting, so the budget measures the payload the caller actually gets; later batches are still sized from stored row width so a narrow projection over wide rows cannot request an oversized SELECT.

The Table block adds a Columns to Return multi-select (table.outputColumns). Empty means all columns; a malformed pick fails fast rather than widening. Deleted columns stay removable in the dropdown (shown by id). Column selectors refetch table detail so deletions show up without a reload. Copied tables keep the pick on fork; mapped tables clear it.

Reviewed by Cursor Bugbot for commit 02f9be3. Bugbot is set up for automated code reviews on this repo. Configure here.

@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR adds selected-column projection to Table v2 queries and carries the selection through the block, tool, API, and row-fetch layers.

  • Resolves column IDs or names against the current table schema and reports unresolved references through ignoredColumns.
  • Projects rows before response-byte accounting while using stored-row measurements to bound full-row database fetches.
  • Adds selector, stale-selection, cache-refresh, and workspace-copy handling for saved column choices.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/sim/lib/table/rows/service.ts Projects selected columns before response-byte accounting and adds stored-average and widest-seen caps to prevent previously observed oversized follow-up fetches.
apps/sim/app/api/table/[tableId]/query/route.ts Resolves requested column references against the authorized table schema and returns unmatched references without widening an invalid selection.
apps/sim/blocks/blocks/table_v2.ts Adds the output-column selector and validates or forwards canvas- and model-supplied column selections.
apps/sim/hooks/selectors/providers/sim/selectors.ts Adds the output-column selector and reads table-detail data through an invalidation-aware query path.
apps/sim/ee/workspace-forking/lib/remap/remap-references.ts Preserves stable column-ID selections when their parent table is copied while continuing to clear them for mapped tables.

Sequence Diagram

sequenceDiagram
  participant Block as Table Block
  participant Tool as Query Rows Tool
  participant Route as Table Query Route
  participant Service as Row Fetch Service
  participant DB as Postgres
  Block->>Tool: columns (stable IDs or names)
  Tool->>Route: query request
  Route->>Route: resolve references against schema
  Route->>Service: resolved columnIds
  loop bounded drain
    Service->>DB: fetch full row batch
    DB-->>Service: stored JSON rows
    Service->>Service: project selected columns
    Service->>Service: account projected and stored bytes
  end
  Service-->>Route: projected rows
  Route-->>Tool: rows + ignoredColumns
Loading

Reviews (3): Last reviewed commit: "fix(tables): bound projected batches by ..." | Re-trigger Greptile

@j15z

j15z commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile

@j15z

j15z commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/table/rows/service.ts

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit cb241af. Configure here.

@j15z

j15z commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile

@j15z

j15z commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit c8151ac. Configure here.

@j15z
j15z merged commit b7073a4 into staging Aug 22, 2026
21 of 23 checks passed

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 02f9be3. Configure here.

const rowBytes = Buffer.byteLength(JSON.stringify(row.data))
const rowStoredBytes = columnIds
? Buffer.byteLength(JSON.stringify(fetchedRow.data))
: rowBytes

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty projection bypasses query budget

Medium Severity

When every columns reference fails to resolve, the route passes an empty Set as columnIds. That value is truthy, so the drain projects each row to {} and the 5MB fail-fast guard only counts those tiny payloads. An unbounded query on a large table can therefore return the full match set (ids and row metadata included) instead of failing at the budget, which risks oversized responses and memory pressure when all selected columns were deleted or mistyped.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 02f9be3. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant